//
//  ServerCommunicator.swift
//  DAL
//
//  Created by raymond Peng on 2018/11/9.
//  Copyright © 2018 raymond Peng. All rights reserved.
//

import Foundation
import Domain

public enum ServerCommunicatorType {
    case urlsession
    case alamofire
}

public class ServerCommunicator {
    public static func instanceOf(type: ServerCommunicatorType) -> IServerCommunicator {
        switch type {
        case .urlsession:
            return URLSessionServerCommunicator.shared
        default:
            fatalError("类型\(type)暂未实现")
        }
    }
}

/// 服务端信使
class URLSessionServerCommunicator: IServerCommunicator {

    static let shared: IServerCommunicator = {
        let config = URLSessionConfiguration.default
        config.timeoutIntervalForResource = 10
        let session = URLSession(configuration: config)
        let communicator = URLSessionServerCommunicator(session: session)
        return communicator
    }()

    private let _session: URLSession

    private init(session: URLSession) {
        _session = session
    }

    func setAddtionalHeaders(_ headers: [String: String]) {
        _session.configuration.httpAdditionalHeaders = headers
    }

    func requestWith(request: IDataRequest, completionHandler: @escaping CommunicationCompletion) {
        let urlRequest = urlRequestFrom(dataRequest: request)
        let task = _session.dataTask(with: urlRequest, completionHandler: { data, resp, error in
            guard error == nil else {
                let code = (resp as? HTTPURLResponse)?.statusCode ?? -65535
                let err = DataError(errorCode: code, errorMessage: error?.localizedDescription ?? "")
                completionHandler(.failed(data: nil, error: err))
                return
            }
            guard let data = data else {
                let err = DataError(errorCode: -65534, errorMessage: "没有接收到数据")
                completionHandler(.failed(data: nil, error: err))
                return
            }
            completionHandler(.success(data: data))
        })
        task.resume()
    }

    private func urlRequestFrom(dataRequest: IDataRequest) -> URLRequest {
        guard var components = URLComponents(url: dataRequest.url, resolvingAgainstBaseURL: false)
            else { fatalError("Unable to create URL components") }

        // 携带 queryString
        components.queryItems = dataRequest.params?.map { param -> URLQueryItem in
            URLQueryItem(name: param.key, value: "\(param.value)")
        }

        // 拿到携带请求参数的完整 URL
        guard let url = components.url else { fatalError("Could not get url") }

        var request = URLRequest(url: url)

        // 请求方法
        request.httpMethod = dataRequest.method.rawValue

        // 设置 Headers
        dataRequest.headers?.forEach({
            request.addValue($1, forHTTPHeaderField: $0)
        })

        // 设置请求体
        request.httpBody = dataRequest.requestBody

        return request
    }
}
